-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update byte_format.cr example to not use uninitialized #15128
Conversation
Even taking a reference to a stack-allocated
|
Interesting, I did not know it worked like that. One could also argue that initialising a How about leaving the current example in, labelling it as unsafe, and adding another, safe example using # Unsafe due to the uninitialized `StaticArray`. The buffer is allocated on the stack, avoiding a heap allocation.
raw = uninitialized UInt8[2]
IO::ByteFormat::LittleEndian.encode(0x1234_i16, raw.to_slice)
raw # => StaticArray[0x34, 0x12]
# Safe, allocated on the heap.
slice = Bytes.new 2
IO::ByteFormat::LittleEndian.encode(0x1234_i16, slice)
slice # => Bytes[0x34, 0x12] |
Sounds good. |
Note: the GC even guarantees that the memory has been initialized to zero. For a larger buffer, like reading from an IO, we might have wanted to explain that it's fine to not initialize the buffer because we will overwrite it anyway. But a 2 bytes buffer? That's not worth it. In fact, the LLVM optimizer will notice that we overwrite the whole memory and only then try to read from it, so the safe initialization can be safely skipped. I compiled a program with that snippet, one function with the safe initializer, and another function with mov $0x34,%edi
mov $0x12,%esi |
Fascinating! What would happen if the bytes to decode were known only at runtime though? In any case, I suppose the docs can be left as they are, as the |
@BigBoyBarney then it wouldn't optimize the byte format call, but it can still detect that the memory is fully written to, and skip the initialization to zero |
Would it be allocated on the heap or the stack? |
No. LLVM has no control over where memory is allocated. There's a RFC 4 to get crystal to do this optimization. |
Very interesting. Thank you! |
Using an unsafe method as the primary example isn't particularly good IMO. Initialising the
StaticArray
with 0s comes with a slight overheard, but I still think it's a better example use-case.